// 展示acm风格的测试方式
// 子矩阵的最大累加和问题，不要求会解题思路，后面的课会讲
// 每一组测试都给定数据规模
// 需要任何空间都动态生成，在大厂笔试或者比赛中，这种方式并不推荐
// 测试链接 : https://www.nowcoder.com/practice/cb82a97dcd0d48a7b1f4ee917e2c0409?
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的code，可以直接通过

#include <bits/stdc++.h>

using namespace std;

inline int read()
{
    char ch = getchar();
    int x = 0, f = 1;
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = 10 * x + ch - '0';
        ch = getchar();
    }
    return f * x;
}

// 求子数组的最大累加和，后面的课会讲
int maxSumSubarray(int* arr, int m)
{
    int mx = INT_MIN;
    int cur = 0;
    for(int i = 0; i < m; ++i)
    {
        cur += arr[i];
        mx = max(mx, cur);
        cur = cur < 0 ? 0 : cur;
    }
    return mx;
}

// 求子矩阵的最大累加和，后面的课会讲
int maxSumSubmatrix(vector<vector<int>>& mat, int n, int m)
{
    int mx = INT_MIN;
    // 将矩阵压缩成数组
    for(int i = 0; i < n; ++i)
    {
        // 需要的辅助数组，临时动态生成就可以
        int arr[m];
        // i ~ j 行的矩阵压缩成 arr 数组
        memset(arr, 0, sizeof arr);
        for(int j = i; j < n; ++j)
        {
            for(int k = 0; k < m; ++k)
            {
                arr[k] += mat[j][k];
            }
            mx = max(mx, maxSumSubarray(arr, m));
        }
    }
    return mx;
}

int main()
{
    int n = read(), m = read();
    vector<vector<int>> arr(n, vector<int>(m));
    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < m; ++j)
        {
            arr[i][j] = read();
        }
    }
    printf("%d\n", maxSumSubmatrix(arr, n, m));

    return 0;
}